package net.lulihu.common_util.jdbc.mapper;

import net.lulihu.common_util.jdbc.DefaultSqlStatementExecutor;
import net.lulihu.common_util.jdbc.MultipleDataSourceManage;
import net.lulihu.common_util.jdbc.SqlStatementExecutor;
import net.lulihu.functional.ConsumerResult;
import org.springframework.jdbc.datasource.DataSourceUtils;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * db映射的父类
 */
public abstract class DatabaseMapper {

    /**
     * 数据源
     */
    private final DataSource dataSource;

    /**
     * sql命令执行者
     */
    private final SqlStatementExecutor sqlStatementExecutor;

    DatabaseMapper() {
        MultipleDataSourceManage dataSourceManage = MultipleDataSourceManage.getInstance();
        this.dataSource = dataSourceManage.getDefaultDataSource();

        this.sqlStatementExecutor = DefaultSqlStatementExecutor.getInstance();
    }

    private DataSource getDataSource() {
        return this.dataSource;
    }

    SqlStatementExecutor getSqlStatementExecutor() {
        return sqlStatementExecutor;
    }

    /**
     * 执行语句
     * <p>
     * 由这个方法来控制数据库连接
     *
     * @param consumer 表达式
     * @param <D>      执行返回值
     * @return 结果
     */
    <D> D execute(ConsumerResult<Connection, D> consumer) {
        Connection connection = DataSourceUtils.getConnection(getDataSource());
        try {
            return consumer.accept(connection);
        } catch (Exception e) {
            // 防止死锁
            DataSourceUtils.releaseConnection(connection, getDataSource());
            throw e;
        } finally {
            DataSourceUtils.releaseConnection(connection, getDataSource());
        }
    }

}
